import javax.swing.*;
import java.awt.event.*;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
/*用户登录界面对象
继承JFrame对象,调用图像化界面的方法
实现ActionListener,重写动作监听方法
 */
public class LoginJFrame extends JFrame implements ActionListener{
    //用户存放用户在集合中的索引
    private int index;

    //集合声明成员变量
    ArrayList<Account> list=null;

    //声明注册界面对象和忘记密码对象
    RegisteJFrame registeJFrame=null;
    ForgetJFrame forgetJFrame=null;

    //新建用户登录,注册,忘记密码按钮
    JButton loginB=new JButton("登录");
    JButton registeB =new JButton("注册");
    JButton forgetPasswordB=new JButton("忘记密码");

    //新建用户名和密码输入框对象
    JTextField userNameField=new JTextField();
    JPasswordField passwordField=new JPasswordField();

    //新建用户名和密码有误提醒弹窗对象
    JDialog userNameWarn =new JDialog();
    JDialog passwordWarn=new JDialog();

    /**
     * 构造方法,初始化用户界面
     * @param list 用户集合
     */
    public LoginJFrame(ArrayList<Account> list) {
        //将本类集合赋值为用户集合
        this.list=list;

        //新建用户注册界面和忘记密码界面对象,但界面不可视
        registeJFrame=new RegisteJFrame(this.list,this);
        forgetJFrame=new ForgetJFrame(this.list,this);

        //界面初始化
        FrameInit();
        //内容初始化
        loginInit();
        //将登录界面设置为可视
        this.setVisible(true);
    }

    /**
     * 索引的获取和设置方法
     * @return 放回索引
     */
    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
    /**
     * 获取和设置用户集合的方法
     * @return 放回用户集合
     */
    public ArrayList<Account> getList() {
        return list;
    }

    public void setList(ArrayList<Account> list) {
        this.list = list;
    }

    /**
     * 界面初始化
     */
    private void FrameInit() {
        //标题设置
        this.setTitle("登录界面");
        //界面大小设置
        this.setSize(400,400);
        //默认关闭方式设置
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //取消界面默认位置
        this.setLocationRelativeTo(null);
    }

    /**
     * 界面内容设置
     */

    private void loginInit() {
        //清空容器内容
        this.getContentPane().removeAll();
        //取消容器默认位置摆放
        this.setLayout(null);
        //新建用户名和密码按钮对象
        JButton userNameB=new JButton("用户名");
        JButton passwordB=new JButton("密码");

        //设置用户名,密码,登录,注册,忘记密码的按钮大小和位置
        userNameB.setBounds(30,70,100,50);
        passwordB.setBounds(30,160,100,50);
        loginB.setBounds(50,250,100,50);
        registeB.setBounds(230,250,100,50);
        forgetPasswordB.setBounds(290,320,90,40);

        //在登录,注册,忘记密码按钮添加动作监听,以本类作为接口的实现类
        loginB.addActionListener(this);
        registeB.addActionListener(this);
        forgetPasswordB.addActionListener(this);

        //将用户名,密码,登录,注册,忘记密码按钮加入容器中
        this.getContentPane().add(userNameB);
        this.getContentPane().add(passwordB);
        this.getContentPane().add(loginB);
        this.getContentPane().add(registeB);
        this.getContentPane().add(forgetPasswordB);

        //新建背景图片对象,并放入图片容器中
        JLabel back=new JLabel(new ImageIcon("src\\back.png"));
        //设置图片大小
        back.setBounds(0,0,400,400);
        //将图片容器加入容器中
        this.getContentPane().add(back);


       //设置用户密码和用户名输入框大小和位置
        userNameField.setBounds(160,70,200,50);
        passwordField.setBounds(160,160,200,50);

        //将用户名和密码加入容器中
        this.getContentPane().add(userNameField);
        this.getContentPane().add(passwordField);

        //刷新界面
        this.getContentPane().repaint();
    }

    /**
     * 重新动作接听方法实现对登录,注册,忘记密码的监听
     * @param actionEvent
     */
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        //判断动作来源
        //若来自登录按钮
        if(actionEvent.getSource()==loginB){
            String userName=new String(userNameField.getText());
            String password=new String(passwordField.getPassword());
            //调用方法,查询用户名对应的索引
            index=userNamecotain(list,userName);
            //判断用户名是否存在
            //若存在
            if(index>=0) {
                //判断密码是否正确
                //若正确
                if (list.get(index).getPassword().equals(password)) {
                    //将登录界面设为不可见
                    this.setVisible(false);
                    //新建登录成功提醒的弹窗
                    JDialog loginwin = new JDialog();
                    //设置弹窗位置,大小,可视化,默认在其他应用上.
                    loginwin.setLocationRelativeTo(null);
                    loginwin.setVisible(true);
                    loginwin.setAlwaysOnTop(true);
                    loginwin.setSize(300, 100);

                    //新建文本容器
                    JLabel tip = new JLabel("恭喜你,成功登录                  --按任意键继续");
                    //将文本容器添加到容器中
                    loginwin.getContentPane().add(tip);

                    //给弹窗添加键盘监听,同时新建匿名内部类实现键盘监听的接口
                    loginwin.addKeyListener(new KeyListener() {
                        @Override
                        public void keyTyped(KeyEvent keyEvent) {
                        }

                        @Override
                        public void keyPressed(KeyEvent keyEvent) {
                        }

                        /**
                         * 重写释放键盘的方法
                         * @param keyEvent
                         */

                        @Override
                        public void keyReleased(KeyEvent keyEvent) {
                            //异常处理
                            try {
                                save();//保存用户信息
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            //按任意键退出程序
                            System.exit(0);
                        }
                    });
                }
                //若密码有误
                else {
                    //将密码错误提醒的弹窗设置位置,大小,可视化,默认关闭方式,默认在顶部
                    passwordWarn.setVisible(true);
                    passwordWarn.setLocationRelativeTo(null);
                    passwordWarn.setDefaultCloseOperation(0);
                    passwordWarn.setAlwaysOnTop(true);
                    passwordWarn.setSize(300,100);

                    //添加密码错误提醒
                    JLabel tip2=new JLabel("用户名和密码不一致,请重新输入      --按任意键继续");
                    passwordWarn.getContentPane().add(tip2);

                    //添加键盘监听对象,通过匿名内部类实现键盘监听接口
                    passwordWarn.addKeyListener(new KeyListener() {
                        @Override
                        public void keyTyped(KeyEvent keyEvent) {

                        }

                        @Override
                        public void keyPressed(KeyEvent keyEvent) {

                        }

                        @Override
                        public void keyReleased(KeyEvent keyEvent) {
                            passwordWarn.setVisible(false);
                            loginInit();
                        }
                    });
                }
            }
            //若用户名有误
            else{
                    //将用户名有误提醒的弹窗设置位置,大小,可视化,默认关闭方式,默认在顶部
                    userNameWarn.setVisible(true);
                    userNameWarn.setLocationRelativeTo(null);
                    userNameWarn.setDefaultCloseOperation(0);
                    userNameWarn.setAlwaysOnTop(true);
                    userNameWarn.setSize(300,100);

                    //新建用户有误提醒对象
                    JLabel tip1=new JLabel("用户名不存在或为空                 --按任意键继续");
                    tip1.setBounds(0,0,200,200);
                    userNameWarn.getContentPane().add(tip1);

                    //将用户名有误的弹窗添加键盘监听,通过匿名内部类实现键盘监听接口
                    userNameWarn.addKeyListener(new KeyListener() {
                        @Override
                        public void keyTyped(KeyEvent keyEvent) {

                        }

                        @Override
                        public void keyPressed(KeyEvent keyEvent) {

                        }

                        /**
                         * 重新键盘释放监听
                         * @param keyEvent
                         */
                        @Override
                        public void keyReleased(KeyEvent keyEvent) {
                            //按任意键
                            //将用户名有误的弹窗设置为不可视
                            userNameWarn.setVisible(false);
                            //登录界面内容重置
                            loginInit();
                        }
                    });
                }
            }
        else {
        //若动作监听为注册按钮
            if(actionEvent.getSource()==registeB){
                //登录界面内容重置
                loginInit();
                //将登录界面设为不可视
                this.setVisible(false);
                //将注册界面设为可视
                registeJFrame.setVisible(true);
            }
            else {
                //若动作监听为忘记密码
                if(actionEvent.getSource()==forgetPasswordB){
                    //重置登录界面内容
                    loginInit();
                    //登录界面视为不可视
                    this.setVisible(false);
                    //将忘记密码界面设为可视
                    forgetJFrame.setVisible(true);
                }
            }
        }
    }

    /**
     * 保存用户信息
     * @throws IOException 抛出用户输出流异常
     */
    private void save() throws IOException {
        //新建用户输出流对象
        FileWriter fw=new FileWriter("src\\accountmessage.txt");
        //循环遍历集合,将用户信息写入文件
        for (int i = 0; i < list.size(); i++) {
            //从集合中获取用户对象
            Account ac=list.get(i);
            //将空格写入文件
            fw.write(' ');
            //将用户姓名写入文件
            fw.write(ac.getUserName());
            fw.write(' ');
            //将密码写入文件
            fw.write(ac.getPassword());
            fw.write(' ');
            //将身份证号写入文件
            fw.write(ac.getId());
            //将换行写入文件
            fw.write('\n');
        }
        //关闭文件输出流通道
        fw.close();
    }

    /**
     * 查询用户名在集合中对应的索引
     * @param list 用户集合
     * @param userName 要查询的字符串
     * @return 返回索引
     */
    private int userNamecotain(ArrayList<Account> list, String userName) {
        //循环查询用户名
        for (int i = 0; i < list.size(); i++) {
            //判断要查询的用户名是否与集合中用户相同
            if(list.get(i).getUserName().equals(userName))
                //若相同,放回索引
                return i;
        }
        //若用户名不存在,返回-1
        return -1;
    }


}
